home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / graphic / xv_pc16a.zip / XBITMAP.PAS < prev    next >
Pascal/Delphi Source File  |  1994-04-22  |  9KB  |  312 lines

  1. PROGRAM XBitmap;
  2. {
  3.  XView-PC for Turbo Pascal demonstration.
  4.  by Antonio Carlos Moreirao de Queiroz - acmq@coe.ufrj.br
  5.  The program reads and plots Windows 16 colors bitmaps.
  6.  Demonstration of use of instances of a window.
  7.  V. 1.0 - 22/05/93
  8.  V. 2.0 - 30/10/93
  9.  V. 2.1 - 22/04/94
  10. }
  11.  
  12. USES Graph,XView;
  13.  
  14. TYPE
  15.   ptr_visor=^visor;
  16.   visor=RECORD {instance of window}
  17.     fwindow,tname,cbitmap,bnew:Xv_opaque;
  18.     pal:ARRAY[0..15] OF RECORD
  19.       r,g,b:INTEGER
  20.     END;
  21.     biHeight,biWidth:INTEGER
  22.   END;
  23.  
  24. VAR
  25.   menuglobal:Xv_opaque;       {menu in all windows}
  26.   memory,terminal:Xv_opaque;  {information window}
  27.   visor1:ptr_visor;           {instance data pointer}
  28.   archive: FILE;              {for reading bitmaps}
  29.   board,mode,iii:INTEGER;     {graphics mode selection}
  30.  
  31. FUNCTION CreateInstance:ptr_visor; FORWARD;
  32. {$F+}
  33. {Here because used in AdjustSize}
  34. PROCEDURE Destroy(w:Xv_opaque); FORWARD;
  35. PROCEDURE ReDraw(obj:Xv_opaque); FORWARD;
  36. {$F-}
  37.  
  38. FUNCTION Si(i:LONGINT):STRING;
  39. VAR
  40.   txt:STRING;
  41. BEGIN
  42.   Str(i,txt);
  43.   Si:=txt
  44. END;
  45.  
  46. FUNCTION Smaller(a,b:WORD):WORD;
  47. BEGIN
  48.   IF a>b THEN Smaller:=b ELSE Smaller:=a
  49. END;
  50.  
  51. FUNCTION AdjustSize(obj:Xv_opaque):BOOLEAN;
  52. {Adjusts the size of the window to the bitmap}
  53. BEGIN
  54.   WITH ptr_visor(obj^.client_data)^ DO BEGIN
  55.     {Turns off the notify_handlers temporarily}
  56.     fwindow^.notify_handler:=Nothing;
  57.     cbitmap^.notify_handler:=Nothing;
  58.     {Closes the window, but impedes the end of the program}
  59.     close_window(fwindow);
  60.     xv_end:=FALSE;
  61.     {Adjusts the size and reopens without redrawing the canvas}
  62.     fwindow^.dx:=BiWidth+2*mrgx+1;
  63.     fwindow^.dy:=BiHeight+mrgx+mrgy+cbitmap^.y+1;
  64.     open_window(fwindow);
  65.     {If impossible...}
  66.     IF not xv_ok THEN BEGIN
  67.       ttysw_output(terminal,'The bitmap is too big'^M^J);
  68.       {Trying a smaller size}
  69.       fwindow^.dy:=200;
  70.       fwindow^.dx:=200;
  71.       open_window(fwindow);
  72.       AdjustSize:=xv_ok
  73.     END
  74.     ELSE AdjustSize:=TRUE;
  75.     {Restores the notify_handlers}
  76.     fwindow^.notify_handler:=Destroy;
  77.     cbitmap^.notify_handler:=ReDraw;
  78.   END
  79. END;
  80.  
  81. {$F+}
  82.  
  83. PROCEDURE Destroy(w:Xv_opaque);
  84. {Instance destructor}
  85. BEGIN
  86.   WITH w^ DO BEGIN
  87.     WITH ptr_visor(client_data)^ DO BEGIN
  88.       {Deallocates the window objects}
  89.       Dispose(fwindow);
  90.       Dispose(tname);
  91.       Dispose(cbitmap);
  92.       Dispose(bnew);
  93.     END;
  94.     Dispose(ptr_visor(client_data)) {Frees the instance data}
  95.   END
  96. END;
  97.  
  98. PROCEDURE ReDraw(obj:Xv_opaque);
  99. {"notify_handler" for the window objects}
  100. VAR
  101.   i,j,k,p,b,kk,ox,oy:WORD;
  102.   buf:ARRAY[0..165] of WORD;
  103.   t,m:BYTE;
  104. LABEL
  105.   Fim;
  106.  
  107. BEGIN
  108.   WITH ptr_visor(obj^.client_data)^ DO BEGIN {With the present instance...}
  109.     IF tname^.panel_value='' THEN Exit;
  110.     Assign(archive,tname^.panel_value);
  111.     {$I-} Reset(archive,2); {$I+}
  112.     IF IOResult<>0 THEN BEGIN
  113.       ttysw_output(terminal,'File '+tname^.panel_value+' not found'^M^J);
  114.       Exit
  115.     END;
  116.     {Reads the bitmap header}
  117.     BlockRead(archive,buf,59);
  118.     IF buf[0]<>$4D42 THEN BEGIN {Starts with 'BM'}
  119.       ttysw_output(terminal,'The file is not a Windows bitmap'^M^J);
  120.       GoTo Fim;
  121.     END;
  122.     biWidth:=buf[9];   {Width}
  123.     biHeight:=buf[11]; {Height}
  124.     IF buf[14]<>4 THEN BEGIN
  125.       ttysw_output(terminal,'Only 16 colors accepted'^M^J);
  126.       GoTo fim
  127.     END;
  128.     {Saves and updates the palette}
  129.     FOR i:=0 TO 15 DO BEGIN
  130.       k:=27+2*i;
  131.       WITH pal[i] DO BEGIN
  132.         r:=Lo(buf[k+1]);
  133.         g:=Hi(buf[k]);
  134.         b:=Lo(buf[k])
  135.       END
  136.     END;
  137.     FOR i:=0 TO 15 DO BEGIN
  138.       WITH pal[i] DO SetRGBPalette(i,r shr 2,g shr 2,b shr 2);
  139.       SetPalette(i,i)
  140.     END;
  141.     {Adjustes the size and plots the bitmap, or at least its lower left corner}
  142.     IF (obj=cbitmap) or AdjustSize(obj) THEN BEGIN
  143.       k:=BiWidth;
  144.       WHILE k mod 8<>0 DO Inc(k);
  145.       k:=k div 4;
  146.       p:=Smaller(cbitmap^.dx-2,biWidth-1);
  147.       {Plots directly in EGA/VGA 16 colors}
  148.       {$IFNDEF DPMI} {Does not work in protected mode}
  149.       IF GetMaxColor=15 THEN BEGIN
  150.         WITH active_w^.gr_out DO BEGIN {viewport}
  151.           ox:=x1;
  152.           oy:=y1;
  153.         END;
  154.         PortW[$3CE]:=$0205; {VGA mode 2}
  155.         FOR j:=Smaller(cbitmap^.dy-2,biHeight-1) DOWNTO 0 DO BEGIN
  156.           BlockRead(archive,buf,k);
  157.           b:=12;
  158.           kk:=(oy+j)*80+ox shr 3; {First byte in the line}
  159.           m:=$80 shr (ox and 7);  {Initial mask}
  160.           FOR i:=0 TO p DO BEGIN
  161.             Port[$3CE]:=$8; {Sets mask}
  162.             Port[$3CF]:=m;
  163.             t:=Mem[$A000:kk]; {Reads byte...}
  164.             Mem[$A000:kk]:=(Swap(buf[i shr 2]) shr b) and $F; {Writes}
  165.             IF b>0 THEN Dec(b,4) ELSE b:=12;
  166.             IF m=1 THEN BEGIN
  167.               m:=$80;
  168.               Inc(kk)
  169.             END
  170.             ELSE m:=m shr 1
  171.           END
  172.         END;
  173.         PortW[$3CE]:=$0005; {Restores mode 0}
  174.         PortW[$3CE]:=$FF08  {Restores mask}
  175.       END
  176.       ELSE
  177.       {$ENDIF}
  178.       BEGIN {Plots with PutPixel - s-l-o-w -}
  179.         FOR j:=Smaller(cbitmap^.dy-2,biHeight-1) DOWNTO 0 DO BEGIN
  180.           BlockRead(archive,buf,k);
  181.           b:=12;
  182.           FOR i:=0 TO p DO BEGIN
  183.             PutPixel(i,j,(Swap(buf[i shr 2]) shr b) and $F);
  184.             IF b>0 THEN Dec(b,4) ELSE b:=12;
  185.           END
  186.         END
  187.       END
  188.     END
  189.   END;
  190.   fim:
  191.     Close(archive);
  192.     ttysw_output(terminal,'MemAvail='+Si(MemAvail)+' MaxAvail='+Si(MaxAvail)+^M^J);
  193. END;
  194.  
  195. PROCEDURE ProcessEvents(obj:Xv_opaque);
  196. {"event_handler" for the canvas}
  197. VAR
  198.   i:INTEGER;
  199. BEGIN {Adjusts the palette if the mouse left button is pressed}
  200.   IF ie_code=MS_LEFT THEN
  201.     WITH ptr_visor(obj^.client_data)^ DO
  202.       IF tname^.panel_value<>'' THEN
  203.         FOR i:=0 TO 15 DO BEGIN
  204.           WITH pal[i] DO SetRGBPalette(i,r shr 2,g shr 2,b shr 2);
  205.           SetPalette(i,i)
  206.         END;
  207. END;
  208.  
  209. PROCEDURE OpenNew(obj:Xv_opaque);
  210. {"notify_handler" for the button}
  211. BEGIN {Creates another panel, if possible}
  212.   visor1:=CreateInstance;
  213.   IF not xv_ok THEN BEGIN
  214.     ttysw_output(terminal,'Impossible to create a new window'^M^J);
  215.     Exit
  216.   END;
  217.   open_window(visor1^.fwindow);
  218.   IF not xv_ok THEN BEGIN
  219.     ttysw_output(terminal,'Impossible to open a new window'^M^J);
  220.     Destroy(visor1^.fwindow);
  221.   END
  222. END;
  223.  
  224. PROCEDURE TratarMenuGlobal(obj:Xv_opaque);
  225. {"notify_handler" do then menu}
  226. VAR
  227.   txt:STRING;
  228.   i,j,k:INTEGER;
  229. BEGIN
  230.   CASE obj^.sel_menu OF
  231.     1:close_window(active_w);
  232.     2:Back;
  233.     3:xv_end:=TRUE;
  234.     4:ttysw_output(terminal,'MemAvail='+Si(MemAvail)+' MaxAvail='+Si(MaxAvail)+^M^J);
  235.   END
  236. END;
  237.  
  238. {$F-}
  239.  
  240. FUNCTION CreateInstance:ptr_visor;
  241. {Creates a new instance}
  242. VAR v:ptr_visor;
  243. BEGIN
  244.   {Tests available memory}
  245.   IF MaxAvail<SizeOf(visor)+5*SizeOf(xv_widget) THEN BEGIN
  246.     xv_ok:=FALSE;
  247.     CreateInstance:=nil;
  248.     Exit
  249.   END;
  250.   New(v);
  251.   WITH v^ DO BEGIN
  252.     normal_client_data:=v;
  253.     fwindow:=xv_create(frame); {Creates the frame}
  254.     WITH fwindow^ DO BEGIN
  255.       xv_label:='Bitmap';
  256.       dx:=226;
  257.       dy:=256;
  258.       menu_name:=menuglobal;
  259.       notify_handler:=Destroy
  260.     END;
  261.     cbitmap:=xv_create(canvas); {Creates the canvas}
  262.     WITH cbitmap^ DO BEGIN
  263.       y:=30;
  264.       notify_handler:=ReDraw;
  265.       event_handler:=ProcessEvents
  266.     END;
  267.     tname:=xv_create(textfield); {Creates the field for the file name}
  268.     WITH tname^ DO BEGIN
  269.       xv_label:='File';
  270.       value_length:=19;
  271.       notify_handler:=ReDraw;
  272.     END;
  273.     bnew:=xv_create(button); {Creates the button that creates another window}
  274.     WITH bnew^ DO BEGIN
  275.       xv_label:='New';
  276.       y:=15;
  277.       notify_handler:=OpenNew;
  278.     END
  279.   END;
  280.   CreateInstance:=v;
  281. END;
  282.  
  283. BEGIN
  284.   board:=0;
  285.   IF ParamCount=2 THEN BEGIN
  286.     Val(ParamStr(1),board,iii);
  287.     Val(ParamStr(2),mode,iii)
  288.   END;
  289.   type_hatch:=InterleaveFill;
  290.   xv_init(board,mode);
  291.   menuglobal:=xv_create(menu); {Creates the menu}
  292.   WITH menuglobal^ DO BEGIN
  293.     item_create('Close');
  294.     item_create('Back');
  295.     item_create('Quit');
  296.     item_create('Memory');
  297.     xv_label:='Window';
  298.     notify_handle